package com.canaan.business.service.storehouse.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.canaan.business.common.enums.storehouse.BarcodeRecordStatusEnum;
import com.canaan.business.common.enums.storehouse.StorehouseStockCheckStatusEnum;
import com.canaan.business.domain.basic.ContainerBarcode;
import com.canaan.business.domain.basic.WmsProduct;
import com.canaan.business.domain.inOutStock.StorehouseStockCheck;
import com.canaan.business.domain.storehouse.WmsBarcodeRecord;
import com.canaan.business.domain.storehouse.WmsStorehouseStock;
import com.canaan.business.domain.vo.BarcodeVo;
import com.canaan.business.mapper.storehouse.WmsBarcodeRecordMapper;
import com.canaan.business.service.basic.IContainerBarcodeService;
import com.canaan.business.service.basic.IWmsCodeRuleProductService;
import com.canaan.business.service.basic.IWmsProductService;
import com.canaan.business.service.inOutStock.IStorehouseStockCheckService;
import com.canaan.business.service.storehouse.IWmsBarcodeRecordService;
import com.canaan.business.service.storehouse.IWmsStorehouseStockService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.StringUtils;
import com.canaan.common.utils.TableNoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.Date;
import java.util.List;


/**
 * 条码记录Service业务层处理
 *
 * @author ruoyi
 * @date 2022-11-30
 */
@Service
public class WmsBarcodeRecordServiceServiceImpl implements IWmsBarcodeRecordService
{
    @Resource
    private WmsBarcodeRecordMapper wmsBarcodeRecordMapper;

    @Autowired
    private IWmsStorehouseStockService iWmsStorehouseStockService;

    @Resource
    private IWmsProductService wmsProductService;

    @Autowired
    protected Validator validator;

    @Autowired
    private IWmsCodeRuleProductService wmsCodeRuleProductService;
    @Autowired
    private IStorehouseStockCheckService storehouseStockCheckService;
    @Resource
    private IContainerBarcodeService containerBarcodeService;

    /**
     * 查询条码记录
     *
     * @param id 条码记录主键
     * @return 条码记录
     */
    @Override
    public WmsBarcodeRecord selectWmsBarcodeRecordById(Long id)
    {
        return wmsBarcodeRecordMapper.selectWmsBarcodeRecordById(id);
    }

    @Override
    public WmsBarcodeRecord getByBarcode(String barcode) {
        return wmsBarcodeRecordMapper.getByBarcode(barcode);
    }

    /**
     * 查询条码记录列表
     *
     * @param wmsBarcodeRecord 条码记录
     * @return 条码记录
     */
    @Override
    public List<WmsBarcodeRecord> selectWmsBarcodeRecordList(WmsBarcodeRecord wmsBarcodeRecord)
    {
        return wmsBarcodeRecordMapper.selectWmsBarcodeRecordList(wmsBarcodeRecord);
    }

    /**
     * 新增条码记录
     *
     * @param wmsBarcodeRecord 条码记录
     * @return 结果
     */
    @Override
    public WmsBarcodeRecord insertWmsBarcodeRecord(WmsBarcodeRecord wmsBarcodeRecord)
    {

        WmsProduct product = wmsProductService.selectWmsProductByProductNo(wmsBarcodeRecord.getProductNo());
        if(product == null){
            throw new ServiceException("物料编号不存在");
        }
        // 如果条码为空，自动生成条码
        if (StringUtils.isEmpty(wmsBarcodeRecord.getBarCode())){
            wmsBarcodeRecord.setBarCode(wmsCodeRuleProductService.getBarcode(product.getProductNo()));
        }
        // 如果条码不为空，使用输入的条码，并判断条码是否已存在
        else {
            WmsBarcodeRecord checkRecord = this.getByBarcode(wmsBarcodeRecord.getBarCode());
            if (checkRecord != null){
                throw new ServiceException("输入的条码存在重复数据，请修改后提交");
            }
        }
        if(wmsBarcodeRecord.getStatus() == null) {
            wmsBarcodeRecord.setStatus(BarcodeRecordStatusEnum.WAIT.getCode());
        }
        wmsBarcodeRecord.setNo(TableNoUtil.getNo(WmsBarcodeRecord.class));
        wmsBarcodeRecord.setProductName(product.getProductName());
        wmsBarcodeRecord.setCreateTime(DateUtils.getNowDate());
        wmsBarcodeRecordMapper.insertWmsBarcodeRecord(wmsBarcodeRecord);
        return wmsBarcodeRecord;
    }

    /**
     * 批量新增条码记录
     *
     * @param barcodeRecordList 条码记录列表
     * @return 结果
     */
    @Override
    public int batchInsertWmsBarcodeRecord(List<WmsBarcodeRecord> barcodeRecordList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        String dateTime = DateUtils.dateTimeNow().substring(2);
        for (WmsBarcodeRecord barcodeRecord : barcodeRecordList){
            barcodeRecord.setBarCode(barcodeRecord.getProductNo() + dateTime);
            if(barcodeRecord.getStatus() == null) {
                barcodeRecord.setStatus(BarcodeRecordStatusEnum.WAIT.getCode());
            }
            barcodeRecord.setCreateBy(username);
            barcodeRecord.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<barcodeRecordList.size();) {
            int endIndex = i+500;
            if (endIndex > barcodeRecordList.size()) {
                endIndex = barcodeRecordList.size();
            }
            insertNum = insertNum + wmsBarcodeRecordMapper.batchInsertWmsBarcodeRecord(barcodeRecordList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改条码记录
     *
     * @param wmsBarcodeRecord 条码记录
     * @return 结果
     */
    @Override
    public int updateWmsBarcodeRecord(WmsBarcodeRecord wmsBarcodeRecord)
    {
        wmsBarcodeRecord.setUpdateTime(DateUtils.getNowDate());
        wmsBarcodeRecord.setUpdateBy(SecurityUtils.getUsername());
        return wmsBarcodeRecordMapper.updateWmsBarcodeRecord(wmsBarcodeRecord);
    }

    /**
     * 批量删除条码记录
     *
     * @param ids 需要删除的条码记录主键
     * @return 结果
     */
    @Override
    public int deleteWmsBarcodeRecordByIds(Long[] ids)
    {
        return wmsBarcodeRecordMapper.deleteWmsBarcodeRecordByIds(ids);
    }

    /**
     * 删除条码记录信息
     *
     * @param id 条码记录主键
     * @return 结果
     */
    @Override
    public int deleteWmsBarcodeRecordById(Long id)
    {
        return wmsBarcodeRecordMapper.deleteWmsBarcodeRecordById(id);
    }

    /**
     * 通过条码获取入库条码信息
     * @param barcodeNo
     * @return
     */
    @Override
    public BarcodeVo getInStockBarcodeInfo(String barcodeNo,String containerNo,Integer isInStock) {
        BarcodeVo barcodeVo = new BarcodeVo();
        WmsBarcodeRecord wmsBarcodeQuery = new WmsBarcodeRecord();
        wmsBarcodeQuery.setBarCode(barcodeNo);
        List<WmsBarcodeRecord> wmsBarcodeRecordList = this.wmsBarcodeRecordMapper.selectWmsBarcodeRecordList(wmsBarcodeQuery);
        WmsBarcodeRecord barcodeRecord = null;
        if(wmsBarcodeRecordList.isEmpty()){
            throw new ServiceException(barcodeNo+"：该条码不存在");
        }else{
            barcodeRecord = wmsBarcodeRecordList.get(0);
            //判断条码是否已绑定容器
            List<ContainerBarcode> containerBarcodeList = containerBarcodeService.selectByBarcode(barcodeNo);
            if (CollectionUtil.isNotEmpty(containerBarcodeList)){
                if (isInStock==1){
                    //如果是扫描入库
                    if (StringUtils.isNotEmpty(containerNo)){
                            if (!containerNo.equals(containerBarcodeList.get(0).getContainerNo())){
                                throw new ServiceException("条码："+barcodeNo+"已绑定容器："+containerBarcodeList.get(0).getContainerNo()+"请扫描容器编号");
                            }
                    }else{
                        throw new ServiceException("条码："+barcodeNo+"已绑定容器："+containerBarcodeList.get(0).getContainerNo()+"请扫描容器编号");
                    }
                }else{
                    //如果是绑定容器
                    throw new ServiceException("条码："+barcodeNo+"已绑定容器："+containerBarcodeList.get(0).getContainerNo());
                }
            }
            WmsBarcodeRecord wmsBarcodeRecord = wmsBarcodeRecordList.get(0);
            WmsProduct product= wmsProductService.selectWmsProductByProductNo(wmsBarcodeRecord.getProductNo());
            if (product!=null){
                barcodeVo.setProductNo(product.getProductNo());
                barcodeVo.setProductName(product.getProductName());
                barcodeVo.setQuantity(wmsBarcodeRecord.getQuantity());
                barcodeVo.setBarCode(barcodeNo);
            }
            barcodeVo.setStatus(barcodeRecord.getStatus().toString());
            //校验该条码是否在待检仓库存里
            StorehouseStockCheck check = storehouseStockCheckService.selectStorehouseStockCheckByBarcode(barcodeNo);
            if(check!=null){
                if(StorehouseStockCheckStatusEnum.TO_BE_INSPECTED.getCode().equals(check.getStatus())){
                    throw new ServiceException("条码："+barcodeNo+"的待检库存状态为待检不能入库");
                }else if(StorehouseStockCheckStatusEnum.INSPECTED_RETURN.getCode().equals(check.getStatus())){
                    throw new ServiceException("条码："+barcodeNo+"的待检库存状态为退货不能入库");
                }else{
                    barcodeVo.setStorehouseLocationNo(check.getStorehouseLocationNo());
                }
            }else{
                WmsStorehouseStock storehouseStockQuery=new WmsStorehouseStock();
                storehouseStockQuery.setBarcode(barcodeNo);
                List<WmsStorehouseStock> storehouseStockList = iWmsStorehouseStockService.selectWmsStorehouseStockList(storehouseStockQuery);
                if (!storehouseStockList.isEmpty()){
                    barcodeVo.setStorehouseLocationNo(storehouseStockList.get(0).getStorehouseLocationNo());
                }
            }
        }
        return barcodeVo;
    }

    @Override
    public BarcodeVo getBindContainBacodeInfo(String barcode) {
        return this.getInStockBarcodeInfo(barcode,null,0);
    }

    @Override
    public BarcodeVo getOutStockBarcodeInfo(String barcode) {
        BarcodeVo barcodeVo = new BarcodeVo();
        WmsStorehouseStock storehouseStockQuery=new WmsStorehouseStock();
        storehouseStockQuery.setBarcode(barcode);
        barcodeVo.setBarCode(barcode);
        List<WmsStorehouseStock> storehouseStockList = iWmsStorehouseStockService.selectWmsStorehouseStockList(storehouseStockQuery);
        if (!storehouseStockList.isEmpty()){
            WmsStorehouseStock wmsStorehouseStock = storehouseStockList.get(0);
            barcodeVo.setStorehouseLocationNo(wmsStorehouseStock.getStorehouseLocationNo());
            barcodeVo.setProductNo(wmsStorehouseStock.getProductNo());
            barcodeVo.setProductName(wmsStorehouseStock.getProductName());
            barcodeVo.setStockQty(wmsStorehouseStock.getQty());
        }else{
            throw new ServiceException("该条码在库存中不存在");
        }
        return barcodeVo;
    }

    @Override
    public WmsBarcodeRecord selectLastBarcode(String barcode) {
        return wmsBarcodeRecordMapper.selectLastBarcode(barcode);
    }

    @Override
    public WmsBarcodeRecord selectWmsBarcodeRecordByBarcode(String barcode) {
        return wmsBarcodeRecordMapper.selectWmsBarcodeRecordByBarcode(barcode);
    }

    @Override
    public int deleteWmsBarcodeRecordByBarcode(String[] barcodes) {
        return wmsBarcodeRecordMapper.deleteWmsBarcodeRecordByBarcode(barcodes);
    }
}
